package xyz.xtt.asset.request;

import java.math.BigDecimal;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

import org.apache.commons.lang3.StringUtils;

import com.google.common.primitives.Longs;

import cn.hutool.core.util.IdUtil;
import jakarta.validation.constraints.DecimalMax;
import jakarta.validation.constraints.DecimalMin;
import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Builder.Default;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import lombok.extern.slf4j.Slf4j;
import xyz.xtt.asset.constants.ErrorMessage;
import xyz.xtt.asset.entity.TblAsset;
import xyz.xtt.asset.entity.TblAssetExt;
import xyz.xtt.asset.entity.TblAssetUserLog;
import xyz.xtt.asset.vo.PreSellInfoVo;
import xyz.xtt.common.asset.AssertUtils;

@Slf4j
@AllArgsConstructor
@NoArgsConstructor
@Data
@ToString
@Builder
public class OperateUpRequest {
	@NotNull(message = "资产goodsId不能为空")
	@NotEmpty(message = "资产goodsId不能为空")
	private String goodsId;
//    @DecimalMin(value = "1.00", message = "售价最小值无效")
	private BigDecimal price;
//    @DecimalMin(value = "1.00", message = "划线价最小值无效")  赠送收到的时候价格也是0
	private BigDecimal guidePirce;
	@DecimalMin(value = "0.01", message = "折扣最小值无效")
	@DecimalMax(value = "10", message = "折扣最大值无效")
	private BigDecimal discount;
	// 2025-03-07 年月日00:00:00
	private String presellStart;
	// 2025-03-09 年月日23:59:59
	private String presellEnd;
	@Default
	private Boolean publiclyVisible = Boolean.FALSE;

	@Min(value = 1, message = "是否同意协议值无效")
	@Max(value = 1, message = "是否同意协议值无效")
	@NotNull(message = "是否同意协议值不能为空")
	private Integer ifAgreed;
	// 版权证明
	private List<String> copyrights;
	// 原创声明
	private List<String> originalCopyrights;

	private Long assetId;

	public TblAssetUserLog buildTblAssetUserLog(String uid, PreSellInfoVo preSellInfoVo, long minutes, Boolean opType, TblAsset asset, TblAssetExt assetExt) {
		Long startPre = preSellInfoVo.getPreStart();
		Long endPre = preSellInfoVo.getPreEnd();
		BigDecimal befDiscount = BigDecimal.ONE;
		Integer befVisible = 1;
		Integer curPubliclyVisible = 0;
		BigDecimal currPrice = opType ? price : asset.getPrice();
		BigDecimal currGuidePirce = opType ? guidePirce : asset.getGuidePrice();

		Long currPresellStart = opType ? startPre : assetExt.getPreSellStartDatetime();
		Long currPresellEnd = opType ? endPre : assetExt.getSellStartDatetime();

		// 公示期天数
		long publicityPeriodDay = TimeUnit.MINUTES.toDays(minutes);
		TblAssetUserLog build = TblAssetUserLog
				.builder()
				.id(IdUtil.getSnowflakeNextId())
				.assetId(asset.getId())
				.opType(opType ? 1 : 0)
				.beforePrice(asset.getPrice())
				.beforeGuidePrice(asset.getGuidePrice())
				.beforeDiscount(befDiscount)
				.beforePubliclyVisible(befVisible)
				.beforePresellStart(Objects.isNull(assetExt.getPreSellStartDatetime()) ? 0L : assetExt.getPreSellStartDatetime())
				.beforePresellEnd(Objects.isNull(assetExt.getSellStartDatetime()) ? 0L : assetExt.getSellStartDatetime())
				.currPrice(currPrice)
				.currGuidePrice(currGuidePirce)
				.currDiscount(befDiscount)
				.currPresellStart(Objects.isNull(currPresellStart) ? 0L : currPresellStart)
				.currPresellEnd(Objects.isNull(currPresellEnd) ? 0L : currPresellEnd)
				.currPubliclyVisible(curPubliclyVisible)
				.isDel(Boolean.FALSE)
				.operateUid(Longs.tryParse(uid))
				.createTime(System.currentTimeMillis())
				.publicityPeriodDay(publicityPeriodDay)
				.ifAgreed(ifAgreed)
				.build();
		Long publicityStart = assetExt.getPublicityPeriodStart();
		Long publicityEnd = assetExt.getPublicityPeriodEnd();
		if (Objects.isNull(publicityStart)) {
			publicityStart = 0L;
		}
		if (Objects.isNull(publicityEnd)) {
			publicityEnd = 0L;
		}
		build.setPublicityPeriodStart(publicityStart);
		build.setPublicityPeriodEnd(publicityEnd);
		return build;
	}

	/**
	 * 预售期是否设置正确
	 *
	 * @param publicityPeriodEnd
	 * @param startPre
	 * @param endPre
	 * @return
	 */
	public boolean checkPresell(Long publicityPeriodEnd, long startPre, long endPre) {
		// 如果开始时间小于当前天的开始
		// 设置有预售期,且预售期开始时间大于公示结束时间
		if (endPre >= startPre && startPre > publicityPeriodEnd) {
			return true;
		}
		log.info("checkPresell presellStart:{},presellEnd:{},publicityPeriodEnd:{} is false", presellStart, presellEnd, publicityPeriodEnd);
		return false;
	}

	/**
	 * 预售期是否是空的
	 *
	 * @return
	 */
	public boolean checkPresellIsNull() {
		// 全部为空才是真空
		// 有一个为空说明两个参数，只传了一个值
		if (StringUtils.isBlank(presellStart) && StringUtils.isBlank(presellEnd)) {
			return true;
		}
		if (StringUtils.isBlank(presellStart) || StringUtils.isBlank(presellEnd)) {
			AssertUtils.isTrue(true, ErrorMessage.CHECK_PRE_SELL_EX, () -> log.info("checkPresell presellStart:{},presellEnd:{}", presellStart, presellEnd));
		}
		return false;
	}

}
